﻿using System;
using System.Configuration;
using System.IO;
using System.Net.Mail;
using System.Net.Mime;
using System.Text;
using System.Web;
using System.Web.Security;
using Beeldbankmvc.Models;
using Elmah;

namespace Beeldbankmvc.Code
{
    public class Notification
    {
        /// <summary>
        /// Sends a notification to all users with role "Administrator", 
        /// notifying them that the specified user account has been locked 
        /// due to the user reaching the maximum of incorrect provided passwords
        /// </summary>
        public static void lockedUserAccount(string name)
        {
            // Get mail addresses of all users with role "Administrator"
            MailAddressCollection recipientAddresses = Email.getUsersByRole("Administrator");

            StreamReader streamReader = new StreamReader(ConfigurationManager.AppSettings["Template"] + "\\blockedUserTemplate.txt");
            string mailText = streamReader.ReadToEnd();
            streamReader.Close();

            mailText = mailText.Replace("[%userName%]", name);
            mailText = mailText.Replace("[%hostUrl%]", Beeldbankmvc.Code.Utility.GetSiteRoot());

            // Send notification email
            Email.sendBCCEMail("Gebruikersaccount geblokkeerd", mailText, recipientAddresses);
        }

        /// <summary>
        /// Sends a notification to all users with role "Administrator", 
        /// notifying them that a new account has been created
        /// </summary>
        public static void accountCreated(string name, string email)
        {
            string bodyUserName = "[%userName%]";
            string emailUserEmail = "[%userEmail%]";

            // Get mail addresses of all users with role "Administrator"
            MailAddressCollection recipientAddresses = Email.getUsersByRole("Administrator");

            StreamReader streamReader = new StreamReader(ConfigurationManager.AppSettings["Template"] + "\\newUserAccountTemplate.txt");
            string mailText = streamReader.ReadToEnd();
            streamReader.Close();

            mailText = mailText.Replace(bodyUserName, name);
            mailText = mailText.Replace(emailUserEmail, email);
            mailText = mailText.Replace("[%hostUrl%]", Beeldbankmvc.Code.Utility.GetSiteRoot());

            // Send notification email
            Email.sendBCCEMail("Nieuw gebruikersaccount", mailText, recipientAddresses);
        }
        
        /// <summary>
        /// Sends the specified reset password to the specified user
        /// </summary>
        /// <param name="user"></param>
        /// <param name="newPassword"></param>
        public static void passwordResetOld(MembershipUser user, string newPassword)
        {
            // Gather user info
            string emailAddress = user.Email;
            string subject = "Beeldarchief password reset";
            string nameRecipient = emailAddress;

            StreamReader streamReader = new StreamReader(ConfigurationManager.AppSettings["Template"] + "\\PasswordForgottenTemplate.txt");
            string mailText = streamReader.ReadToEnd();
            streamReader.Close();

            mailText = mailText.Replace("[%newPassword%]", newPassword);
            mailText = mailText.Replace("[%hostUrl%]", Beeldbankmvc.Code.Utility.GetSiteRoot());

            UserRepository userRepository = new UserRepository();
            EditAccountModel userModel = userRepository.FindOne(new Guid(user.ProviderUserKey.ToString()));

            // If additional data exists for this user, use its first and last name as recipient name
            if (userModel != null)
                nameRecipient = userModel.FirstName + " " + userModel.LastName;

            // Create recipient object
            MailAddress recipient = new MailAddress(emailAddress, nameRecipient);

            // Send email to user
            Email.sendSystemEMail(subject, mailText, recipient, true);
        }
        
        private static String mailtext(MembershipUser user, string newPassword, bool isHtml)
        {
            String closingTag = "";
            if (isHtml)
                closingTag = "<br />";

            StringBuilder sb = new StringBuilder();
            sb.AppendLine("Beste , " + user.UserName + " " + closingTag);
            sb.AppendLine("" + closingTag);
            sb.AppendLine("U heeft uw wachtwoord opgevraagd van de Beeldarchief Rijkswaterstaat website." + closingTag);
            sb.AppendLine("Dit zijn uw inloggegevens: " + closingTag);
            sb.AppendLine("Website adres: https://beeldbank.rws.nl " + closingTag);
            sb.AppendLine("Gebruikersnaam:  " + user.UserName + " " + closingTag);
            sb.AppendLine("Wachtwoord: " + newPassword + " " + closingTag);
            sb.AppendLine("" + closingTag);
            sb.AppendLine("Met vriendelijke groeten, " + closingTag);
            sb.AppendLine("Helpdesk Beeldarchief Rijkswaterstaat" + closingTag);
            sb.AppendLine("" + closingTag);
            sb.AppendLine("*NB: als u uw wachtwoord niet heeft opgevraagd, dan kunt u dit bericht negeren " + closingTag);

            return sb.ToString();
        }

        /// <summary>
        /// Sends the specified reset password to the specified user
        /// </summary>
        /// <param name="user"></param>
        /// <param name="newPassword"></param>
        public static void passwordReset(MembershipUser user, string newPassword)
        {
            // Mail message construction
            MailMessage eMailMessage = new MailMessage(Email.sendingEmail, user.Email);
            eMailMessage.Subject = "Beeldarchief Wachtwoord opvragen";

            // use mail template
            StreamReader streamReader = new StreamReader(ConfigurationManager.AppSettings["Template"] + "\\nieuwsbriefTemplate.html");
            string mailText = streamReader.ReadToEnd();
            streamReader.Close();

            mailText = mailText.Replace("[%imageUrl%]", "cid:RijkswaterstaatHeader");
            mailText = mailText.Replace("[%Title%]", "Beeldarchief Wachtwoord opvragen");
            mailText = mailText.Replace("[%SubTitle%]", "");
            mailText = mailText.Replace("[%Bodytext%]", mailtext(user, newPassword, true));
            mailText = mailText.Replace("[%hostUrl%]", Beeldbankmvc.Code.Utility.GetSiteRoot());

            AlternateView avHtml = AlternateView.CreateAlternateViewFromString(mailText, null, MediaTypeNames.Text.Html);

            // Now, linking our image as an embedded resource
            LinkedResource RijkswaterstaatHeader = new LinkedResource(ConfigurationManager.AppSettings["Template"] + "\\RWS_HeaderMail.gif", MediaTypeNames.Image.Gif);
            RijkswaterstaatHeader.ContentId = "RijkswaterstaatHeader";

            // Linking the image
            avHtml.LinkedResources.Add(RijkswaterstaatHeader);

            // For clients that do not support HTML content
            string textBody = mailtext(user, newPassword, false);

            AlternateView avText = AlternateView.CreateAlternateViewFromString(textBody, null, MediaTypeNames.Text.Plain);

            // Add the alternate views
            eMailMessage.AlternateViews.Add(avHtml);
            eMailMessage.AlternateViews.Add(avText);

            // Sending message
            SmtpClient client = new SmtpClient(Email.SMTPHost, 25);

            // our account credentials
            client.DeliveryMethod = SmtpDeliveryMethod.Network;
            client.UseDefaultCredentials = true;

            // Catching result
            try
            {
                client.Send(eMailMessage);
            }
            catch (SmtpException ex)
            {
                // Log exception
                var context = HttpContext.Current;
                ErrorLog.GetDefault(context).Log(new Error(ex, context));
            }
            catch (Exception ex)
            {
                // Log exception
                var context = HttpContext.Current;
                ErrorLog.GetDefault(context).Log(new Error(ex, context));
            }
        }

        /// <summary>
        /// Sends a notification message to the email address specified in the web.config file, 
        ///  informing this person about a new reaction on the web site
        /// </summary>
        /// <param name="emailAddress"></param>
        /// <param name="nameCreator"></param>
        /// <param name="subject"></param>
        /// <param name="category"></param>
        /// <param name="message"></param>
        public static void newReactionCreated(string emailAddress, string nameCreator, string subject, string category, string message)
        {
            string recipientEmail = ConfigurationManager.AppSettings["reactionMailToAddress"].ToString();
            string recipientName = ConfigurationManager.AppSettings["reactionMailToName"].ToString();

            // Create recipient object
            MailAddress creatorSender = new MailAddress(emailAddress, nameCreator);

            string body = "Categorie: " + category + "\n\n" + "Boodschap: " + message;

            MailAddress recipientAddress = new MailAddress(recipientEmail, recipientName); 

            // Send email to user
            Email.sendEMail(subject, body, recipientAddress, creatorSender);
        }

        /// <summary>
        /// Sends a notification message to the email address specified in mediaObject modifiedby aka the owner
        /// </summary>
        /// <param name="emailAddress"></param>
        /// <param name="nameCreator"></param>
        /// <param name="subject"></param>
        /// <param name="category"></param>
        /// <param name="message"></param>
        public static void newReactionOnMediaObjectCreated(string emailOwner, string nameOwner, int mediaObjectId)
        {
            string subject = "Er is een reactie gegeven op een media object";

            string recipientEmail = emailOwner;
            string recipientName = nameOwner;

            MailAddress recipientAddress = new MailAddress(emailOwner, nameOwner);

            // Use mail template
            StreamReader streamReader = new StreamReader(ConfigurationManager.AppSettings["Template"] + "\\ReactionMediaObjectTemplate.txt");
            string mailText = streamReader.ReadToEnd();
            streamReader.Close();

            mailText = mailText.Replace("[%hostUrl%]", Beeldbankmvc.Code.Utility.GetSiteRoot());
            mailText = mailText.Replace("[%MediaObjectId%]", mediaObjectId.ToString());
            mailText = mailText.Replace("[%userName%]", recipientName);
            
            // Send email to user
            Email.sendSystemEMail(subject, mailText, recipientAddress, true);
        }

        /// <summary>
        /// Sends a notification message to the email address specified in mediaObject modifiedby aka the owner
        /// </summary>
        /// <param name="emailAddress"></param>
        /// <param name="nameCreator"></param>
        /// <param name="subject"></param>
        /// <param name="category"></param>
        /// <param name="message"></param>
        public static void newRequestForPublishingMediaObject(MailAddress publisherAddress,int mediaObjectId)
        {
            string subject = "Er is een aanvraag voor het publiceren van een media object";

            // Use mail template
            StreamReader streamReader = new StreamReader(ConfigurationManager.AppSettings["Template"] + "\\RequestPublishMediaObjectTemplate.txt");
            string mailText = streamReader.ReadToEnd();
            streamReader.Close();

            mailText = mailText.Replace("[%hostUrl%]", Beeldbankmvc.Code.Utility.GetSiteRoot());
            mailText = mailText.Replace("[%MediaObjectId%]", mediaObjectId.ToString());
            mailText = mailText.Replace("[%userName%]", publisherAddress.DisplayName);

            // Send email to user
            Email.sendSystemEMail(subject, mailText, publisherAddress, true);
        }

        /// <summary>
        /// Sends a notification message to the email address specified in mediaObject modifiedby aka the owner
        /// </summary>
        /// <param name="emailAddress"></param>
        /// <param name="nameCreator"></param>
        /// <param name="subject"></param>
        /// <param name="category"></param>
        /// <param name="message"></param>
        public static void newRejectionForPublishingMediaObject(MailAddress publisherAddress, int mediaObjectId)
        {
            string subject = "Uw aanvraag voor het publiceren van een media object is afgewezen";

            // Use mail template
            StreamReader streamReader = new StreamReader(ConfigurationManager.AppSettings["Template"] + "\\RejectPublishMediaObjectTemplate.txt");
            string mailText = streamReader.ReadToEnd();
            streamReader.Close();

            mailText = mailText.Replace("[%hostUrl%]", Beeldbankmvc.Code.Utility.GetSiteRoot());
            mailText = mailText.Replace("[%MediaObjectId%]", mediaObjectId.ToString());
            mailText = mailText.Replace("[%userName%]", publisherAddress.DisplayName);

            // Send email to user
            Email.sendSystemEMail(subject, mailText, publisherAddress, true);
        }

        /// <summary>
        /// Send a fake auto reply message from the admin computer to the user
        /// </summary>
        /// <param name="emailAddress"></param>
        /// <param name="nameCreator"></param>
        /// <param name="subject"></param>
        /// <param name="category"></param>
        /// <param name="message"></param>
        public static void autoRespondReactionCreated(string emailAddress, string nameCreator, string subject, string category, string message)
        {
            string recipientEmail = ConfigurationManager.AppSettings["sendingEmail"].ToString();
            string recipientName = ConfigurationManager.AppSettings["nameSender"].ToString();

            // Create recipient object
            MailAddress creatorSender = new MailAddress(recipientEmail, recipientName);

            string body = "Geachte " + nameCreator + ",\n\nWij hebben uw reactie ontvangen.\nU ontvangt uiterlijk binnen 5 werkdagen van ons een reactie.\n\nMet vriendelijke groeten,\n\nHelpdesk Beeldarchief Rijkswaterstaat";

            MailAddress recipientAddress = new MailAddress(emailAddress, nameCreator);

            // Send email to user
            Email.sendEMail(subject, body, recipientAddress, creatorSender);
        }

        /// <summary>
        /// Send a backup of the submited data to the user
        /// </summary>
        /// <param name="emailAddress"></param>
        /// <param name="nameCreator"></param>
        /// <param name="subject"></param>
        /// <param name="category"></param>
        /// <param name="message"></param>
        public static void backupReactionCreated(string emailAddress, string nameCreator, string subject, string category, string message)
        {
            string recipientEmail = ConfigurationManager.AppSettings["sendingEmail"].ToString();
            string recipientName = ConfigurationManager.AppSettings["nameSender"].ToString();

            // Create recipient object
            MailAddress creatorSender = new MailAddress(recipientEmail, recipientName);

            string body = "Geachte " + nameCreator + ",\n\nU heeft ons de volgende reactie gestuurd:\n\nCategorie: " + category + "\n\n" +
                "Boodschap: " + message + "\n\nU ontvangt uiterlijk binnen 5 werkdagen van ons een reactie.\n\nMet vriendelijke groeten,\n\nHelpdesk Beeldarchief Rijkswaterstaat";

            MailAddress recipientAddress = new MailAddress(emailAddress, nameCreator); 

            // Send email to user
            Email.sendEMail(subject, body, recipientAddress, creatorSender);
        }

        public static void verifyNewAccount(MembershipUser newUser)
        {
            string subject = "Bevestig uw Beeldarchief aanmelding";

            string recipientEmail = newUser.Email;
            string recipientName = newUser.UserName;

            // Create recipient object
            MailAddress creatorSender = new MailAddress(recipientEmail, recipientName);

            // Use mail template
            StreamReader streamReader = new StreamReader(ConfigurationManager.AppSettings["Template"] + "\\verifyUserAccountTemplate.txt");
            string mailText = streamReader.ReadToEnd();
            streamReader.Close();

            mailText = mailText.Replace("[%hostUrl%]", Beeldbankmvc.Code.Utility.GetSiteRoot());
            mailText = mailText.Replace("[%userKey%]", newUser.ProviderUserKey.ToString());
            mailText = mailText.Replace("[%userName%]", newUser.UserName);

            MailAddress recipientAddress = new MailAddress(recipientEmail, recipientName);

            // Send email to user
            Email.sendSystemEMail(subject, mailText, recipientAddress, true);
        }

        public static void reactionResponse(MailAddress recipientAddress, String URLkey)
        {
            string subject = "Uw vraag aan Beeldarchief Rijkswaterstaat is bijgewerkt";

            string recipientEmail = recipientAddress.Address;
            string recipientName = recipientAddress.DisplayName;

            // Create recipient object

            // Use mail template
            StreamReader streamReader = new StreamReader(ConfigurationManager.AppSettings["Template"] + "\\ReactionResponseTemplate.txt");
            string mailText = streamReader.ReadToEnd();
            streamReader.Close();
                        
            mailText = mailText.Replace("[%hostUrl%]", Beeldbankmvc.Code.Utility.GetSiteRoot());
            mailText = mailText.Replace("[%key%]", URLkey);
            mailText = mailText.Replace("[%userName%]", recipientName);
            
            // Send email to user
            Email.sendSystemEMail(subject, mailText, recipientAddress, true);
        }

        public static void reactionOnMediaResponse(MailAddress recipientAddress, String action, int mediaObjectId)
        {
            string subject = "Uw reactie op een media item van Beeldarchief Rijkswaterstaat is " + action.ToLower();

            string recipientEmail = recipientAddress.Address;
            string recipientName = recipientAddress.DisplayName;

            // Create recipient object

            // Use mail template
            StreamReader streamReader = new StreamReader(ConfigurationManager.AppSettings["Template"] + "\\reactionOnMediaObjectTemplate.txt");
            string mailText = streamReader.ReadToEnd();
            streamReader.Close();

            mailText = mailText.Replace("[%action%]", action);
            mailText = mailText.Replace("[%hostUrl%]", Beeldbankmvc.Code.Utility.GetSiteRoot());
            mailText = mailText.Replace("[%MediaObjectId%]", mediaObjectId.ToString());
            mailText = mailText.Replace("[%userName%]", recipientName);
            
            // Send email to user
            Email.sendSystemEMail(subject, mailText, recipientAddress, true);
        }
    }
}